require('./');

var assign = require('object-assign');

var express = module.parent ? module.parent.require('express') : require('express');

patchResponse(express.response);
delete require.cache[__filename];

module.exports = function markoAppMiddleware() {
    var sacrificialApp = express();

    sacrificialApp.once('mount', function onmount(parent) {
        // Patch the response
        patchResponse(parent.response);

        // Remove sacrificial express app
        if (parent._router) {
            // Support Express <= 4.x
            parent._router.stack.pop();
        } else {
            // Support express 5.x
            parent.router.stack.pop();
        }
    });

    return sacrificialApp;
};

function patchResponse(response) {
    response.marko = response.marko || function(template, data) {
        if(typeof template === 'string') {
            throw new Error(
                'res.marko does not take a template name or path like res.render.  ' +
                'Instead you should use `require(\'./path/to/template.marko\')` ' +
                'and pass the loaded template to this function.'
            );
        }

        var res = this;
        var req = res.req;
        var app = res.app;
        var $global = assign({ app, req, res }, app.locals, res.locals);

        if (data) {
            data = assign(data, {
                $global: assign($global, data.$global)
            });
        } else {
            data = { $global };
        }

        res.set({ 'content-type': 'text/html; charset=utf-8' });

        return template.render(data, res);
    };
}
